package com.ruoyi.system.service.impl;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.uuid.Seq;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.RemoteFileDataService;
import com.ruoyi.system.api.domain.File;
import com.ruoyi.system.api.domain.SysSerialConfig;
import com.ruoyi.system.api.domain.SysSerialOption;
import com.ruoyi.system.mapper.SysSerialConfigMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.SysSerialMapper;
import com.ruoyi.system.api.domain.SysSerial;
import com.ruoyi.system.service.ISysSerialService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 流水号配置Service业务层处理
 * 
 * @author ruoyi
 * @date 2023-04-14
 */
@Service
public class SysSerialServiceImpl implements ISysSerialService 
{
    private static final Logger log = LoggerFactory.getLogger(SysSerialServiceImpl.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private SysSerialMapper sysSerialMapper;

    @Autowired
    private SysSerialConfigMapper sysSerialConfigMapper;
    @Autowired
    private RemoteFileDataService remoteFileDataService;

    /**
     * 查询流水号配置
     * 
     * @param serialId 流水号配置主键
     * @return 流水号配置
     */
    @Override
    public SysSerial selectSysSerialBySerialId(Long serialId)
    {
        SysSerial sysSerial = sysSerialMapper.selectSysSerialBySerialId(serialId);
        //编码规范文档
        R<List<File>> fileListResult = remoteFileDataService.selectFileList(sysSerial.getSerialId(),"23", SecurityConstants.INNER);
        if (StringUtils.isNotNull(fileListResult) && StringUtils.isNotNull(fileListResult.getData())){
            sysSerial.setFileList(fileListResult.getData());
        }
        return sysSerial;
    }

    /**
     * 查询流水号配置列表
     * 
     * @param sysSerial 流水号配置
     * @return 流水号配置
     */
    @Override
    public List<SysSerial> selectSysSerialList(SysSerial sysSerial)
    {
        return sysSerialMapper.selectSysSerialList(sysSerial);
    }

    /**
     * 新增流水号配置
     * 
     * @param sysSerial 流水号配置
     * @return 结果
     */
    @Transactional
    @Override
    public Long insertSysSerial(SysSerial sysSerial)
    {
        Long orgId = SecurityUtils.getOrgId();
        if(sysSerial.getIsRel() == 1 && sysSerial.getRelId() == null) {
            throw new ServiceException("请选择引用的编号!");
        }
        if(StringUtils.isNotNull(sysSerial.getSerialId())){
            Integer count = jdbcTemplate.queryForObject("select count(*) from sys_serial where org_id =? and del_flag = 0 and serial_id <> ? and serial_name =?",Integer.class,orgId,sysSerial.getSerialId(),sysSerial.getSerialName().trim());
            if(count > 0){
                log.error(sysSerial.getSerialName() + "已存在!");
                throw new ServiceException(sysSerial.getSerialName() + "已存在!");
            }
            Integer count1 = jdbcTemplate.queryForObject("select count(*) from sys_serial where org_id =? and del_flag = 0 and serial_id <> ? and type_id = ?",Integer.class,orgId,sysSerial.getSerialId(),sysSerial.getTypeId());
            if(count1 > 0){
                log.error("该应用场景已经被编号占用,无法使用");
                throw new ServiceException("该应用场景已经被编号占用,无法使用");
            }
            //引用其它编号
            if(sysSerial.getIsRel() == 1){
                if(sysSerial.getRelId().longValue() == sysSerial.getSerialId().longValue()){
                    throw new ServiceException("引用编号不能选择自己!");
                }
                List<Long> configIdList = sysSerialConfigMapper.selectConfigIdBySerialId(sysSerial.getSerialId());
                if(configIdList.size() > 0){
                    Long[] configIds = configIdList.toArray(new Long[configIdList.size()]);
                    sysSerialConfigMapper.deleteSysSerialConfigByConfigIds(configIds);
                    sysSerialConfigMapper.deleteSysSerialOptionByConfigIds(configIds);
                }
            }
            sysSerialMapper.updateSysSerial(sysSerial);
        }
        else{
            Integer count = jdbcTemplate.queryForObject("select count(*) from sys_serial where org_id =? and del_flag = 0  and serial_name =?",Integer.class,orgId,sysSerial.getSerialName().trim());
            if(count > 0){
                log.error(sysSerial.getSerialName() + "已存在!");
                throw new ServiceException(sysSerial.getSerialName() + "已存在!");
            }
            Integer count1 = jdbcTemplate.queryForObject("select count(*) from sys_serial where org_id =? and del_flag = 0 and type_id = ?",Integer.class,orgId,sysSerial.getTypeId());
            if(count1 > 0){
                log.error("该应用场景已经被编号占用,无法使用");
                throw new ServiceException("该应用场景已经被编号占用,无法使用");
            }
            sysSerial.setSerialId(Seq.getSeqId());
            sysSerial.setOrgId(SecurityUtils.getLoginUser().getSysUser().getOrgId());
            sysSerial.setCreateUserId(SecurityUtils.getUserId());
            sysSerial.setCreateUserName(SecurityUtils.getLoginUser().getSysUser().getNickName());
            sysSerialMapper.insertSysSerial(sysSerial);
        }
        //编码规范文档
        List<Long> fileIds = sysSerial.getFileList().stream().map(File::getFileId).collect(Collectors.toList());
        remoteFileDataService.saveFileList(sysSerial.getSerialId(),23,fileIds, SecurityConstants.INNER);
        return sysSerial.getSerialId();
    }

    /**
     * 批量删除流水号配置
     * 
     * @param serialIds 需要删除的流水号配置主键
     * @return 结果
     */
    @Override
    public int deleteSysSerialBySerialIds(Long[] serialIds)
    {
        return sysSerialMapper.deleteSysSerialBySerialIds(serialIds);
    }

    /**
     * 删除流水号配置信息
     * 
     * @param serialId 流水号配置主键
     * @return 结果
     */
    @Override
    public int deleteSysSerialBySerialId(Long serialId)
    {
        return sysSerialMapper.deleteSysSerialBySerialId(serialId);
    }


    @Override
    @Transactional
    public int updateSerial() {
        Long orgId = 1721435614948831234L;
        Long userId = 1721435615536033793L;
        Map<Long,Long> map = new HashMap<>();
        List<SysSerial> sysSerialList = jdbcTemplate.query("select * from sys_serial  where org_id = 168 AND  del_flag = 0", new BeanPropertyRowMapper<>(SysSerial.class));
        String sql = "insert into sys_serial(serial_id, org_id, serial_name, type_id, current_value, current_split_value, next_value, create_user_id, create_time, create_user_name)values(?,?,?,?,?,?,?,?,sysdate(),?)";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                SysSerial sysSerial = sysSerialList.get(i);
                long serialId = Seq.getSeqId();
                ps.setLong(1,serialId );
                ps.setLong(2,orgId);
                ps.setString(3, sysSerial.getSerialName());
                ps.setInt(4, sysSerial.getTypeId());
                if (sysSerial.getCurrentValue() == null){
                    ps.setNull(5, Types.INTEGER);
                }else{
                    ps.setInt(5, sysSerial.getCurrentValue());
                }
                if (sysSerial.getCurrentSplitValue() == null){
                    ps.setNull(6, Types.VARCHAR);
                }else{
                    ps.setString(6, sysSerial.getCurrentSplitValue());
                }
                if (sysSerial.getNextValue() == null){
                    ps.setNull(7, Types.INTEGER);
                }else{
                    ps.setInt(7, sysSerial.getNextValue());
                }
                ps.setLong(8, userId);
                ps.setString(9,"测试检测有限公司");
                map.put(sysSerial.getSerialId(),serialId);
            }
            @Override
            public int getBatchSize() {
                return sysSerialList.size();
            }
        });
        List<SysSerialConfig> sysSerialConfigList = jdbcTemplate.query("select * from sys_serial_config c inner join sys_serial s on c.serial_id = s.serial_id where c.org_id = 168 and s.del_flag = 0 ", new BeanPropertyRowMapper<>(SysSerialConfig.class));
        Map<Long, Long> configMap = new HashMap<>();
        for (SysSerialConfig sysSerialConfig : sysSerialConfigList) {
            long configId = Seq.getSeqId();
            configMap.put(sysSerialConfig.getConfigId(),configId);
        }
        String sql1 = "insert into sys_serial_config(config_id, serial_id, config_type, config_name, config_value, max_length, rel_config_id, org_id, create_time, update_time,write_type,add_zero,order_num)values(?,?,?,?,?,?,?,?,sysdate(),sysdate(),?,?,?)";
        jdbcTemplate.batchUpdate(sql1, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                SysSerialConfig config = sysSerialConfigList.get(i);
                ps.setLong(1,configMap.get(config.getConfigId()));
                ps.setLong(2,map.get(config.getSerialId()));
                ps.setInt(3, config.getConfigType());
                ps.setString(4, config.getConfigName());
                if (config.getConfigValue() == null){
                    ps.setNull(5, Types.VARCHAR);
                }else{
                    ps.setString(5, config.getConfigValue());
                }
                if (config.getMaxLength() == null){
                    ps.setNull(6, Types.BIGINT);
                }else{
                    ps.setInt(6, config.getMaxLength());
                }
                if (config.getRelConfigId() == null){
                    ps.setNull(7, Types.VARCHAR);
                }else{
                    String relConfigId = config.getRelConfigId();
                    String[] relConfigIds = relConfigId.split(",");
                    StringBuilder s = new StringBuilder();
                    for (String configId : relConfigIds) {
                        Long aLong = configMap.get(Long.parseLong(configId));
                        s.append(",").append(aLong);
                    }
                    ps.setString(7, s.substring(1));
                }
                ps.setLong(8, orgId);
                if (config.getWriteType() == null){
                    ps.setNull(9, Types.BIGINT);
                }else{
                    ps.setInt(9, config.getWriteType());
                }
                if (config.getAddZero() == null){
                    ps.setNull(10, Types.BIGINT);
                }else{
                    ps.setInt(10, config.getAddZero());
                }
                if (config.getOrderNum() == null){
                    ps.setNull(11, Types.BIGINT);
                }else{
                    ps.setInt(11, config.getOrderNum());
                }
            }
            @Override
            public int getBatchSize() {
                return sysSerialConfigList.size();
            }
        });
        List<SysSerialOption> sysSerialOptionList = jdbcTemplate.query("select * from sys_serial_option o inner join sys_serial_config c on o.config_id = c.config_id inner join sys_serial s on s.serial_id=c.serial_id  where o.org_id = 168 and s.del_flag =0 ", new BeanPropertyRowMapper<>(SysSerialOption.class));
        String sql2 = "insert into sys_serial_option(config_id, value, label, org_id)values(?,?,?,?)";
        jdbcTemplate.batchUpdate(sql2, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                SysSerialOption option = sysSerialOptionList.get(i);
                ps.setLong(1,configMap.get(option.getConfigId()));
                ps.setString(2,option.getValue());
                ps.setString(3, option.getLabel());
                ps.setLong(4, orgId);
            }
            @Override
            public int getBatchSize() {
                return sysSerialOptionList.size();
            }
        });
     return 1;
    }
}
